package jumpingnotes.security;

import java.util.Calendar;
import java.util.UUID;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class SessionManager
{
	private Log log = LogFactory.getLog(SessionManager.class);

	protected int timeout = 30;
	protected int interval = 15;

	protected ConcurrentHashMap<String, Session> sessionMap;

	public SessionManager()
	{
		sessionMap = new ConcurrentHashMap<String, Session>();

		new Thread()
		{
			@Override
			public void run()
			{
				while (true)
				{
					try
					{
						Thread.sleep(interval * 60 * 1000);
					}
					catch (InterruptedException e)
					{
						e.printStackTrace();
					}

					log.debug("Checking expired session...");
					removeExpire();
				}
			}
		}.start();
	}

	public String createSession(String email)
	{
		String id = UUID.randomUUID().toString();
		Session session = new Session(id, email);
		refreshExpire(session);

		sessionMap.put(id, session);
		log.debug("Session created: " + session);

		return id;
	}

	public Session accessSession(String id)
	{
		Calendar now = Calendar.getInstance();

		Session session = sessionMap.get(id);
		if (session != null && now.before(session.getExpire()))
		{
			log.debug("Session found: " + id);

			refreshExpire(session);
			log.debug("Session updated: " + session);

			return session;
		}

		log.debug("Session not found: " + id);

		return null;
	}

	public Session accessSession(String id, String email)
	{
		Calendar now = Calendar.getInstance();

		Session session = sessionMap.get(id);
		if (session != null && email != null && email.equals(session.getEmail()) && now.before(session.getExpire()))
		{
			log.debug("Session found: " + id);

			refreshExpire(session);
			log.debug("Session updated: " + session);

			return session;
		}

		log.debug("Session not found: " + id);

		return null;
	}

	protected void removeExpire()
	{
		Calendar now = Calendar.getInstance();

		for (Entry<String, Session> entry : sessionMap.entrySet())
		{
			String id = entry.getKey();
			Session session = entry.getValue();

			if (now.after(session.getExpire()))
			{
				sessionMap.remove(id);
				log.debug("Session removed: " + session);
			}
		}
	}

	protected void refreshExpire(Session session)
	{
		Calendar expire = Calendar.getInstance();
		expire.add(Calendar.MINUTE, timeout);
		session.setExpire(expire);
	}

	public ConcurrentHashMap<String, Session> getSessionMap()
	{
		return sessionMap;
	}
	
	public void setTimeout(int timeout)
	{
		this.timeout = timeout;
	}

	public void setInterval(int interval)
	{
		this.interval = interval;
	}
}
